using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Diagnostics;
using Microsoft.MediaCenter.UI;
using System.Xml;
using MusicBrowser.Util;
using System.Reflection;
using TagLib;



namespace MusicBrowser.LibraryManagement
{
    public class FolderItem : BaseFolderItem
    {
        #region Constructors

        public FolderItem()
        {
            // we need this so we can construct these puppies for mcml params 
            thumbPath = "";
        }

        public FolderItem(string filename, bool isFolder)
            : this (filename, isFolder, 
                isFolder ? 
                    System.IO.Path.GetFileName(filename) : 
                    System.IO.Path.GetFileNameWithoutExtension(filename))
        {
        }


        public FolderItem(string filename, bool isFolder, string description)
        {
            this.filename = filename;
            this.isFolder = isFolder;
            this.Description = description;

        }

        #endregion 

        #region Statics
        private static MD5CryptoServiceProvider CryptoService = new MD5CryptoServiceProvider();
        static object syncObj = new object();
        #endregion 

        #region Privates 

        VirtualFolder virtualFolder = null;
        private string path = null;
        bool thumbLoaded = false;
        DateTime createdDate = DateTime.MinValue;
        DateTime modifiedDate = DateTime.MinValue;
        List<IFolderItem> contents;
        string filename;
        bool isFolder;
        string thumbPath;
        DateTime thumbDate = DateTime.MinValue;
        


        #endregion 

        public VirtualFolder VirtualFolder {
            get
            {
                return virtualFolder; 
            }
            set 
            {
                if (value.ThumbPath != null)
                {
                   ThumbPath = value.ThumbPath;
                }
                virtualFolder = value;
            } 
        }

        public override string Album
        {
            get
            {
                           
                string rval = string.Empty;
                if (IsSong)
                {
                    return tag("Album");
                }
                return rval;
            }
        }

        public override string Artist
        {
           get
            {
                           
                string rval = string.Empty;
                if (IsSong)
                {
                    return tag("Artist");
                }
                return rval;
            }
        }

        public override string Title
        {
            get
            {
                           
                string rval = string.Empty;
                if (IsSong)
                {
                    return tag("Title");
                }
                else if (IsPlaylist)
                {
                    return "playlist";
                }
                return rval;
            }
       
        }

        public override string mainTitle
        {
           get
            {
                           
                string rval = string.Empty;
                if (IsSong)
                {
                    if (Title == null)
                    {
                        return System.IO.Path.GetFileNameWithoutExtension(filename);
                    }
                    else
                    {
                        return Title;
                    }
                }
                else if (IsPlaylist)
                {
                    return "playlist";
                }
                return rval;
            }
        }

        public override string Duration
        {
           get
            {
                           
                string rval = string.Empty;
                if (IsSong)
                {
                    return tag("Duration");
                }
                return rval;
            }
        }

       



        public string tag(string type)
        {
            if (!System.IO.File.Exists(filename)) return string.Empty;
            FileStream fs = System.IO.File.OpenRead(filename);
            TagLib.File fileTag;
            try
            {
                fileTag = TagLib.File.Create(filename);
            }
            catch { return string.Empty; }

            if (type == "Image")
            {
                TagLib.Picture cover = null;
                foreach (TagLib.Picture pic in fileTag.Tag.Pictures)
                    if (pic.Type == TagLib.PictureType.FrontCover)
                    {
                        cover = pic;
                        break;
                    }
                return null;
            }

            
            if (type == "Title") return fileTag.Tag.Title;
            if (type == "Album")
            {
                if (fileTag.Tag.Year == 0)
                {
                    return fileTag.Tag.Album;
                }
                else
                {
                    return fileTag.Tag.Album + "  (" + fileTag.Tag.Year + ")";
                }
            }
            if (type == "Artist") return fileTag.Tag.FirstPerformer;
            if (type == "Duration")
            {
                TimeSpan tmp = fileTag.Properties.Duration;
                if (tmp.Seconds < 10)
                {
                    return tmp.Minutes + ":0" + tmp.Seconds;
                }
                else
                {
                    return tmp.Minutes + ":" + tmp.Seconds;
                }
            }

            return null;                        
        }

               
        public string Path 
        {
            get 
            {
                if (path == null)
                {
                    path = System.IO.Path.GetDirectoryName(filename); 

                 }
                return path;
            }
            set
            {
                path = value;
            }
        }

        // used for genre navigation   
        public List<IFolderItem> Contents { 
            get 
            {
                return contents; 
            }
            set 
            {
                contents = value; 
            }
        }

     

        public override DateTime CreatedDate
        {
            get 
            {
                if (createdDate == DateTime.MinValue)
                {
                    InitTimes();
                }

                return createdDate;
            }
           
        }



        public override DateTime ModifiedDate
        {
            get
            {
                LoadModifiedDate();

                return modifiedDate;
            }
        }

        public void LoadModifiedDate()
        {
            if (modifiedDate == DateTime.MinValue)
            {
                DirectoryInfo di = new DirectoryInfo(filename);
                modifiedDate = di.LastWriteTime;
            }
        }

        public override string Filename
        {
            get { return filename; }
        }

        public override bool IsFolder
        {
            get { return isFolder; }
        }


        public override string ThumbHash
        {
            get
            {
                string key = ThumbPath;
                key += ThumbDate.ToString();
                key = Helper.HashString(key) + System.IO.Path.GetExtension(ThumbPath);
                return key;
            } 
        }


        public long ThumbDate
        {
            get
            {
                if (thumbDate == DateTime.MinValue)
                {

                    try
                    {
                        DirectoryInfo di = new DirectoryInfo(ThumbPath);
                        thumbDate = di.LastWriteTime;
                    }
                    catch
                    {
                        thumbDate = DateTime.MaxValue;
                    }
                }
                return thumbDate.ToBinary();
            } 
        } 

        public override string ThumbPath 
        {
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    thumbPath = value;
                    thumbLoaded = true;
                }
                else
                {
                    thumbLoaded = false;
                    thumbPath = "";
                }
            }
            get
            {
                if (filename == null)
                {
                    return null;
                } 

                if (!thumbLoaded)
                { 
                    var tp = Helper.GetThumb(filename,IsFolder);
                    thumbLoaded = true;
                    if (!string.IsNullOrEmpty(tp))
                    {
                        thumbPath = tp; 
                    }
                }

                

                return thumbPath; 
            }
        }


       

        public override string ToString()
        {
            return Description;
        }

        public override bool IsSong
        {
            get
            {
                return Helper.IsSong(filename); 
            } 
        }

        public override bool IsPlaylist
        {
            get
            {
                return Helper.IsPlaylist(filename); 
            }
        } 

        
       

      

        public Guid Hash
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(this.createdDate.ToString());
                sb.Append(this.IsFolder.ToString());
                sb.Append(this.IsSong.ToString());
                sb.Append(this.IsPlaylist.ToString());
                sb.Append(this.ThumbPath == null ? "<null>" : this.thumbPath);
                sb.Append(this.filename);
                sb.Append(this.Path);

                Byte[] originalBytes = ASCIIEncoding.Default.GetBytes(sb.ToString());
                Byte[] encodedBytes = CryptoService.ComputeHash(originalBytes);
                return new Guid(encodedBytes);
            } 
        }

      

       
  
        private void InitTimes()
        {
            try
            {
                // dont care about times for non files 
                if (filename == null)
                {
                    return;
                }

                DirectoryInfo di = new DirectoryInfo(filename);
                modifiedDate = di.LastWriteTime;
                if (!IsFolder || !IsSong)
                {
                    createdDate = di.CreationTime;    
                }
                
            }
            catch (Exception e)
            {
                Trace.WriteLine(filename);
                Trace.WriteLine(e.ToString());
            }

            //Trace.WriteLine(this.Displayname + " " + createdDate.ToString());
        }

      

      

    }

   
}
